#include<iostream>
using namespace std;
#include "student.h"
#include "grade_analysis.h"
#include "fun_achieve.h"
#include<string>
#include<iomanip>
#include<algorithm>
#include<fstream>

//以下是自定义比较函数
bool sort_math_des(Student s1, Student s2)
{
    return s1.GetMath() > s2.GetMath();
}

bool sort_math_asc(Student s1, Student s2)
{
    return s1.GetMath() < s2.GetMath();
}

bool sort_en_des(Student s1, Student s2)
{
    return s1.GetEnglish() > s2.GetEnglish();
}

bool sort_en_asc(Student s1, Student s2)
{
    return s1.GetEnglish() < s2.GetEnglish();
}

bool sort_pol_des(Student s1, Student s2)
{
    return s1.GetPolitics() > s2.GetPolitics();
}

bool sort_pol_asc(Student s1, Student s2)
{
    return s1.GetPolitics() < s2.GetPolitics();
}

bool sort_pro_des(Student s1, Student s2)
{
    return s1.GetPro() > s2.GetPro();
}

bool sort_pro_asc(Student s1, Student s2)
{
    return s1.GetPro() < s2.GetPro();
}

bool sort_total_des(Student s1, Student s2)
{
    return s1.GetTotal() > s2.GetTotal();
}

bool sort_total_asc(Student s1, Student s2)
{
    return s1.GetTotal() < s2.GetTotal();
}

//显示所有学生信息
void FunAchieve::ShowAllMessage(vector<Student>& v)
{
    char c;
    cout << "\n\n################学生信息列表################\n\n" << endl;
    if (v.size())
    {
        int j = 0;
        cout.setf(ios::left);
        cout << setw(10) << "序号" << setw(20) << "学号" << setw(15) << "姓名" << setw(15) << "年级" << setw(15) << "班级" << setw(15) << "数学成绩" << setw(15) << "英语成绩" << setw(15) << "政治成绩" << setw(15) << "专业成绩" << setw(15) << "总成绩" << endl;
        for (auto & it : v)
        {
            j++;
            cout << setw(10) << j << setw(20) << it.stu_num << setw(15) << it.stu_name << setw(15) << it.stu_grade << setw(15) << it.stu_class << setw(15) << it.GetMath() << setw(15) << it.GetEnglish() << setw(15) << it.GetPolitics() << setw(15) << it.GetPro() << setw(15) << it.stu_total << endl;
        }
        cin.ignore();
        cout << "\n\n################已显示所有学生信息，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
    else
    {
        cin.ignore();
        cout << "\n\n################当前学生信息列表为空，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
}

//录入学生信息
void FunAchieve::AddMessage(vector<Student>& v)
{
    int num;
    char c;
    Student temp;
    cout << "\n\n################录入学生信息################\n\n" << endl;
    cout << "请输入要添加的人数：";
    cin >> num;
    for (int i = 0; i < num; i++)
    {
        cout << "------------------请输入第" << i + 1 << "个人的信息------------------" << endl;
        cout << "请输入姓名：";
        cin >> temp.stu_name;
        cout << "请输入学号(学号为8-16位数字或字母)：";
        cin >> temp.stu_num;
        while (temp.stu_num.size() > 16 || temp.stu_num.size() < 8)
        {
            cout << "学号有误，请重新输入！" << endl;
            cout << "请输入学号(学号为8-16位数字或字母)：";
            cin >> temp.stu_num;
        }
        cout << "请输入年级：";
        cin >> temp.stu_grade;
        cout << "请输入班级：";
        cin >> temp.stu_class;
        cout << "请输入数学成绩：";
        cin >> temp.stu_score[0];
        //temp.stu_score[0] =((double)((int)((temp.stu_score[0] + 0.005) * 100))) / 100;
        cout << "请输入英语成绩：";
        cin >> temp.stu_score[1];
        //temp.stu_score[1] = ((double)((int)((temp.stu_score[1] + 0.005) * 100))) / 100;
        cout << "请输入政治成绩：";
        cin >> temp.stu_score[2];
        //temp.stu_score[2] = ((double)((int)((temp.stu_score[2] + 0.005) * 100))) / 100;
        cout << "请输入专业成绩：";
        cin >> temp.stu_score[3];
        //temp.stu_score[3] = ((double)((int)((temp.stu_score[3] + 0.005) * 100))) / 100;
        temp.CalTotal();
        v.push_back(temp);
    }
    cin.ignore();
    cout << "\n\n################已成功录入学生信息，请按回车键返回主菜单！################\n\n" << endl;
    if ((c = cin.get()) == '\n')
        return;
}

//删除学生信息
void FunAchieve::RemoveMessage(vector<Student>& v)
{
    char c;
    cout << "\n\n################删除学生信息################\n\n" << endl;
    if (v.size())
    {
        int flag = 0, num = 1;
        while (num)
        {

            string s;
            cout << "请输入需要删除的学生的学号：";
            cin >> s;
            for (auto it = v.begin(); it != v.end(); ++it)
            {
                if (s == (*it).stu_num)
                {
                    v.erase(it);
                    flag = 1;
                    break;
                }
            }
            if (flag)
            {
                cout << "\n\n################已成功删除该学生信息，请选择是否继续使用删除功能（输入1继续，输入0退出）################\n\n" << endl;
                cin >> num;
                cout << endl;
            }
            else {
                cout << "\n\n################不存在该学生信息，请选择是否继续使用删除功能（输入1继续，输入0退出）################\n\n" << endl;
                cin >> num;
                cout << endl;
            }
        }
    }
    else
    {
        cin.ignore();
        cout << "\n\n################当前学生信息列表为空，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
}

//查询学生信息
void FunAchieve::SearchMessage(vector<Student>& v)
{
    char c;
    cout << "\n\n################查询学生信息################\n\n" << endl;
    if (v.size())
    {
        string s;
        int flag = 0, num = 1;
        cout.setf(ios::left);
        while (num)
        {
            flag = 0;
            cout << "请输入需要查询的学生的学号：";
            cin >> s;
            for (auto it = v.begin(); it != v.end(); ++it)
            {
                if (s == (*it).stu_num)
                {
                    cout << "\n\n------------------该生信息如下------------------\n\n" << endl;
                    cout << setw(20) << "学号" << setw(15) << "姓名" << setw(15) << "年级" << setw(15) << "班级" << setw(15) << "数学成绩" << setw(15) << "英语成绩" << setw(15) << "政治成绩" << setw(15) << "专业成绩" << setw(15) << "总成绩" << endl;
                    cout << setw(20) << (*it).stu_num << setw(15) << (*it).stu_name << setw(15) << (*it).stu_grade << setw(15) << (*it).stu_class << setw(15) << (*it).GetMath() << setw(15) << (*it).GetEnglish() << setw(15) << (*it).GetPolitics() << setw(15) << (*it).GetPro() << setw(15) << (*it).stu_total << endl;
                    flag = 1;
                    break;
                }
            }
            if (flag)
            {
                cout << "\n\n################已显示该学生信息，请选择是否继续使用查询功能（输入1继续，输入0退出）################\n\n" << endl;
                cin >> num;
                cout << endl;
            }
            else {
                cout << "\n\n################不存在该学生信息，请选择是否继续使用查询功能（输入1继续，输入0退出）################\n\n" << endl;
                cin >> num;
                cout << endl;
            }
        }
    }
    else
    {
        cin.ignore();
        cout << "\n\n################当前学生信息列表为空，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
}

//修改学生信息
void FunAchieve::UpdateMessage(vector<Student>& v)
{
    char c;
    cout << "\n\n################修改学生信息################\n\n" << endl;
    if (v.size())
    {
        string s;
        int num = 0, flag = 0, num2 = 1;
        cout.setf(ios::left);
        while (num2)
        {
            flag = 0;
            cout << "请输入需要修改的学生的学号：";
            cin >> s;
            for (auto it = v.begin(); it != v.end(); ++it)
            {
                if (s == (*it).stu_num)
                {
                    cout << "\n\n------------------该生信息如下------------------\n\n" << endl;
                    cout << setw(20) << "学号" << setw(15) << "姓名" << setw(15) << "年级" << setw(15) << "班级" << setw(15) << "数学成绩" << setw(15) << "英语成绩" << setw(15) << "政治成绩" << setw(15) << "专业成绩" << setw(15) << "总成绩" << endl;
                    cout << setw(20) << (*it).stu_num << setw(15) << (*it).stu_name << setw(15) << (*it).stu_grade << setw(15) << (*it).stu_class << setw(15) << (*it).GetMath() << setw(15) << (*it).GetEnglish() << setw(15) << (*it).GetPolitics() << setw(15) << (*it).GetPro() << setw(15) << (*it).stu_total << endl;
                    cout << "\n\n------------------请选择需要修改的内容------------------\n\n";
                    cout << setw(20) << "1.学号" << setw(15) << "2.姓名" << setw(15) << "3.年级" << setw(15) << "4.班级" << setw(15) << "5.数学成绩" << setw(15) << "6.英语成绩" << setw(15) << "7.政治成绩" << setw(15) << "8.专业成绩" << setw(15) << "9.总成绩" << endl;
                    cout << "\n\n请选择对应的序号(输入0退出修改)：";
                    cin >> num;
                    while (num != 0)
                    {
                        if (num == 0) break;
                        if (num == 1)
                        {
                            cout << "请输入新的学号：";
                            cin >> (*it).stu_num;
                        }
                        else if (num == 2)
                        {
                            cout << "请输入新的姓名：";
                            cin >> (*it).stu_name;
                        }
                        else if (num == 3)
                        {
                            cout << "请输入新的年级：";
                            cin >> (*it).stu_grade;
                        }
                        else if (num == 4)
                        {
                            cout << "请输入新的班级：";
                            cin >> (*it).stu_class;
                        }
                        else if (num == 5)
                        {
                            cout << "请输入新的数学成绩：";
                            cin >> (*it).stu_score[0];
                        }
                        else if (num == 6)
                        {
                            cout << "请输入新的英语成绩：";
                            cin >> (*it).stu_score[1];
                        }
                        else if (num == 7)
                        {
                            cout << "请输入新的政治成绩：";
                            cin >> (*it).stu_score[2];
                        }
                        else if (num == 8)
                        {
                            cout << "请输入新的专业成绩：";
                            cin >> (*it).stu_score[3];
                        }
                        else {
                            cout << "输入的序号有误，请重新输入！" << endl;
                        }
                        cout << "\n\n请选择对应的序号(输入0退出修改)：";
                        cin >> num;
                    }
                    flag = 1;
                    (*it).CalTotal();
                    break;
                }
            }
            if (flag)
            {
                cout << "\n\n################已修改该学生信息，请选择是否继续使用修改功能（输入1继续，输入0退出）################\n\n" << endl;
                cin >> num2;
                cout << endl;
            }
            else {
                cout << "\n\n################不存在该学生信息，请选择是否继续使用修改功能（输入1继续，输入0退出）################\n\n" << endl;
                cin >> num2;
                cout << endl;
            }
        }
    }
    else
    {
        cin.ignore();
        cout << "\n\n################当前学生信息列表为空，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
}

//对学生信息进行排序
void FunAchieve::SortMessage(vector<Student>& v)
{
    char c;
    cout << "\n\n################对学生信息进行排序################\n\n" << endl;
    if (v.size())
    {
        int num = 0;
        cout.setf(ios::left);
        cout << setw(30) << "1.对数学成绩进行排序" << setw(30) << "2.对英语成绩进行排序" << setw(30) << "3.对政治成绩进行排序" << setw(30) << "4.对专业成绩进行排序" << setw(30) << "5.对总成绩进行排序" << setw(30) << "0.退出" << endl;
        cout << "\n请选择对应的序号：";
        cin >> num;
        while (num) {
            if (num > 5 || num < 0)
            {
                cout << "输入的序号有误,请重新输入！\n\n";
                cout << setw(30) << "1.对数学成绩进行排序" << setw(30) << "2.对英语成绩进行排序" << setw(30) << "3.对政治成绩进行排序" << setw(30) << "4.对专业成绩进行排序" << setw(30) << "5.对总成绩进行排序" << setw(30) << "0.退出" << endl;
            }
            switch (num)
            {
                case 0:
                    break;
                case 1:
                    cout << setw(30) << "\n1.对数学成绩进行升序" << setw(30) << "2.对数学成绩进行降序" << endl;
                    cout << "\n请选择对应的序号：";
                    cin >> num;
                    while (num != 1 && num != 2)
                    {
                        cout << "输入的序号有误，请重新输入！" << endl;
                        cout << setw(30) << "\n1.对数学成绩进行升序" << setw(30) << "2.对数学成绩进行降序" << endl;
                        cout << "\n请选择对应的序号：";
                        cin >> num;
                    }
                    if (num == 1)
                    {
                        cin.ignore();
                        sort(v.begin(), v.end(), sort_math_asc);
                        cout << "\n\n################已对学生信息根据数学成绩进行升序排序，请按回车键返回主菜单！################\n\n" << endl;
                        if ((c = cin.get()) == '\n')
                            return;
                    }
                    else if (num == 2)
                    {
                        cin.ignore();
                        sort(v.begin(), v.end(), sort_math_des);
                        cout << "\n\n################已对学生信息根据数学成绩进行降序排序，请按回车键返回主菜单！################\n\n" << endl;
                        if ((c = cin.get()) == '\n')
                            return;
                    }
                    break;
                case 2:
                    cout << setw(30) << "\n1.对英语成绩进行升序" << setw(30) << "2.对英语成绩进行降序" << endl;
                    cout << "\n请选择对应的序号：";
                    cin >> num;
                    while (num != 1 && num != 2)
                    {
                        cout << "输入的序号有误，请重新输入！" << endl;
                        cout << setw(30) << "\n1.对英语成绩进行升序" << setw(30) << "2.对英语成绩进行降序" << endl;
                        cout << "\n请选择对应的序号：";
                        cin >> num;
                    }
                    if (num == 1)
                    {
                        cin.ignore();
                        sort(v.begin(), v.end(), sort_en_asc);
                        cout << "\n\n################已对学生信息根据英语成绩进行升序排序，请按回车键返回主菜单！################\n\n" << endl;
                        if ((c = cin.get()) == '\n')
                            return;
                    }
                    else if (num == 2)
                    {
                        cin.ignore();
                        sort(v.begin(), v.end(), sort_en_des);
                        cout << "\n\n################已对学生信息根据英语成绩进行降序排序，请按回车键返回主菜单！################\n\n" << endl;
                        if ((c = cin.get()) == '\n')
                            return;
                    }
                    break;
                case 3:
                    cout << setw(30) << "\n1.对政治成绩进行升序" << setw(30) << "2.对政治成绩进行降序" << endl;
                    cout << "\n请选择对应的序号：";
                    cin >> num;
                    while (num != 1 && num != 2)
                    {
                        cout << "输入的序号有误，请重新输入！" << endl;
                        cout << setw(30) << "\n1.对政治成绩进行升序" << setw(30) << "2.对政治成绩进行降序" << endl;
                        cout << "\n请选择对应的序号：";
                        cin >> num;
                    }
                    if (num == 1)
                    {
                        cin.ignore();
                        sort(v.begin(), v.end(), sort_pol_asc);
                        cout << "\n\n################已对学生信息根据政治成绩进行升序排序，请按回车键返回主菜单！################\n\n" << endl;
                        if ((c = cin.get()) == '\n')
                            return;
                    }
                    else if (num == 2)
                    {
                        cin.ignore();
                        sort(v.begin(), v.end(), sort_pol_des);
                        cout << "\n\n################已对学生信息根据政治成绩进行降序排序，请按回车键返回主菜单！################\n\n" << endl;
                        if ((c = cin.get()) == '\n')
                            return;
                    }
                    break;
                case 4:
                    cout << setw(30) << "\n1.对专业成绩进行升序" << setw(30) << "2.对专业成绩进行降序" << endl;
                    cout << "\n请选择对应的序号：";
                    cin >> num;
                    while (num != 1 && num != 2)
                    {
                        cout << "输入的序号有误，请重新输入！" << endl;
                        cout << setw(30) << "\n1.对专业成绩进行升序" << setw(30) << "2.对专业成绩进行降序" << endl;
                        cout << "\n请选择对应的序号：";
                        cin >> num;
                    }
                    if (num == 1)
                    {
                        cin.ignore();
                        sort(v.begin(), v.end(), sort_pro_asc);
                        cout << "\n\n################已对学生信息根据专业成绩进行升序排序，请按回车键返回主菜单！################\n\n" << endl;
                        if ((c = cin.get()) == '\n')
                            return;
                    }
                    else if (num == 2)
                    {
                        cin.ignore();
                        sort(v.begin(), v.end(), sort_pro_des);
                        cout << "\n\n################已对学生信息根据专业成绩进行降序排序，请按回车键返回主菜单！################\n\n" << endl;
                        if ((c = cin.get()) == '\n')
                            return;
                    }
                    break;
                case 5:
                    cout << setw(30) << "\n1.对总成绩进行升序" << setw(30) << "2.对总成绩进行降序" << endl;
                    cout << "\n请选择对应的序号：";
                    cin >> num;
                    while (num != 1 && num != 2)
                    {
                        cout << "输入的序号有误，请重新输入！" << endl;
                        cout << setw(30) << "\n1.对总成绩进行升序" << setw(30) << "2.对总成绩进行降序" << endl;
                        cout << "\n请选择对应的序号：";
                        cin >> num;
                    }
                    if (num == 1)
                    {
                        cin.ignore();
                        sort(v.begin(), v.end(), sort_total_asc);
                        cout << "\n\n################已对学生信息根据总成绩进行升序排序，请按回车键返回主菜单！################\n\n" << endl;
                        if ((c = cin.get()) == '\n')
                            return;
                    }
                    else if (num == 2)
                    {
                        cin.ignore();
                        sort(v.begin(), v.end(), sort_total_des);
                        cout << "\n\n################已对学生信息根据总成绩进行降序排序，请按回车键返回主菜单！################\n\n" << endl;
                        if ((c = cin.get()) == '\n')
                            return;
                    }
                    break;
            }
            cout << "\n请选择对应的序号：";
            cin >> num;
        }
    }
    else
    {
        cin.ignore();
        cout << "\n\n################当前学生信息列表为空，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }

}

//成绩统计分析
void FunAchieve::AnalyMessage(vector<Student>& v)
{
    char c;
    GradeAnalysis a;
    cout << "\n\n################成绩统计分析################\n\n" << endl;
    if (v.size())
    {
        cout.setf(ios::fixed);
        cout.precision(2);
        cout << "数学平均分：" << a.AvgMath(v) << endl;
        cout << "英语平均分：" << a.AvgEn(v) << endl;
        cout << "政治平均分：" << a.AvgPol(v) << endl;
        cout << "专业平均分：" << a.AvgPro(v) << endl;
        cout << "总成绩平均分：" << a.AvgTotal(v) << endl;
        //恢复默认格式
        cout.unsetf(ios::fixed);
        cout.precision(0);
        cout << "\n挂科人数：" << a.FailNum(v) << endl;
        cout << "挂科人名：";
        a.OutputName(v);
        cin.ignore();
        cout << "\n\n################已成功统计学生信息，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
    else
    {
        cin.ignore();
        cout << "\n\n################当前学生信息列表为空，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
}

//清空学生信息
void FunAchieve::ClearMessage(vector<Student>& v)
{
    char c;
    cout << "\n\n################清空学生信息################\n\n" << endl;
    if (v.size())
    {
        v.clear();
        cin.ignore();
        cout << "\n\n################已成功清空所有学生信息，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
    else
    {
        cin.ignore();
        cout << "\n\n################当前学生信息列表为空，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
}

//从文本文件中读入
void FunAchieve::InputFile(vector<Student>& v)
{
    char c;
    string s;
    Student temp;
    ifstream input("grade_manage_in.txt");
    cout << "\n\n################从文本文件中读入################\n\n" << endl;
    getline(input, s);
    while (!input.eof())
    {
        input >> temp.stu_num >> temp.stu_name >> temp.stu_grade >> temp.stu_class >> temp.stu_score[0] >> temp.stu_score[1] >> temp.stu_score[2] >> temp.stu_score[3];
        if (!input.eof()) {
            temp.CalTotal();
            v.push_back(temp);
        }
    }
    input.close();
    cin.ignore();
    cout << "\n\n################已成功录入学生信息，请按回车键返回主菜单！################\n\n" << endl;
    if ((c = cin.get()) == '\n')
        return;
}

//保存到文本文件
void FunAchieve::OutputFile(vector<Student>& v)
{
    char c;
    cout << "\n\n################保存到文本文件################\n\n" << endl;
    if (v.size())
    {
        ofstream outputfile;
        outputfile.open("grade_manage_out.txt");
        int j = 0;
        outputfile.setf(ios::left);
        outputfile << setw(10) << "序号\t" << "学号\t\t" << "姓名\t" << "年级\t" << "班级\t" << "数学成绩\t\t" << "英语成绩\t\t" << "政治成绩\t\t" << "专业成绩\t\t" << "总成绩" << endl;
        for (auto it = v.begin(); it != v.end(); ++it)
        {
            j++;
            outputfile << setw(10) << j << setw(23) << (*it).stu_num << setw(12) << (*it).stu_name << setw(15) << (*it).stu_grade << setw(15) << (*it).stu_class << setw(30) << (*it).GetMath() << setw(30) << (*it).GetEnglish() << setw(30) << (*it).GetPolitics() << setw(27) << (*it).GetPro() << setw(10) << (*it).stu_total << endl;
        }
        outputfile.close();
        cin.ignore();
        cout << "\n\n################已保存所有学生信息，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
    else
    {
        cin.ignore();
        cout << "\n\n################当前学生信息列表为空，请按回车键返回主菜单！################\n\n" << endl;
        if ((c = cin.get()) == '\n')
            return;
    }
}